package com.kang.listener;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kang.bean.bot.play2.Lv;
import com.kang.bean.bot.play2.Role;
import com.kang.bean.bot.play2.Speed;
import com.kang.bean.bot.play2.vo.RoleVo;
import com.kang.manager.BotAutoManager;
import com.kang.service.play2.LvService;
import com.kang.service.play2.RoleService;
import com.kang.service.play2.SpeedService;
import com.kang.service.play2.impl.RoleServiceImpl;
import lombok.extern.slf4j.Slf4j;
import love.forte.common.ioc.annotation.Beans;
import love.forte.common.ioc.annotation.Depend;
import love.forte.common.ioc.annotation.PrePass;
import love.forte.simbot.annotation.Filter;
import love.forte.simbot.annotation.OnGroup;
import love.forte.simbot.annotation.OnPrivate;
import love.forte.simbot.annotation.OnlySession;
import love.forte.simbot.api.message.events.GroupMsg;
import love.forte.simbot.api.message.events.PrivateMsg;
import love.forte.simbot.api.message.events.PrivateMsgRecall;
import love.forte.simbot.api.sender.Sender;
import love.forte.simbot.filter.MatchType;
import love.forte.simbot.listener.ContinuousSessionScopeContext;
import love.forte.simbot.listener.ListenerContext;
import love.forte.simbot.listener.SessionCallback;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @author K.faWu
 * @program service
 * @description: 问大天荒
 * @create 2022-08-19 15:07
 **/
@Slf4j
@Beans
@Component
public class Play2Listener {
    @Depend
    @Autowired
    private BotAutoManager botAutoManager;
    @Autowired
    private SpeedService speedService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private LvService lvService;

    /**
     * 开始加入的分组
     */
    private static final String INIT = "init";
    /**
     * 选择性别
     */
    private static final String SEX = "sex";
    /**
     * 名字
     */
    private static final String NAME = "name";

    public static final String CHOICE = "choice";

    /**
     * 开始游戏，抽取角色属性
     */
    @Filter(value = "加入大陆", matchType = MatchType.EQUALS)
    @OnPrivate
    public void init(PrivateMsg privateMsg, ListenerContext context, Sender sender) {

        // 得到session上下文，并断言它的确不是null
        final ContinuousSessionScopeContext sessionContext = (ContinuousSessionScopeContext) context.getContext(ListenerContext.Scope.CONTINUOUS_SESSION);
        assert sessionContext != null;

        final String accountCode = privateMsg.getAccountInfo().getAccountCode();

        sender.sendPrivateMsg(privateMsg, "请输入昵称(不超过6个字符)：");

        // 创建回调函数 SessionCallback 实例。
        // 通过 SessionCallback.builder 进行创建
        final SessionCallback<String> callback = SessionCallback.<String>builder().onResume(name -> {
            sender.sendPrivateMsg(privateMsg, "角色：" + name + "，请选择性别(男/女)：");
            sessionContext.waiting(SEX, accountCode, sex -> {
                sender.sendPrivateMsg(privateMsg, "角色生成中...");
                //创建角色
                Role role = roleService.init(accountCode, name, sex.toString());
                Speed speed = RoleServiceImpl.getSpeedMap().get(role.getGasNum().longValue());
                //展示角色信息
                sender.sendPrivateMsg(privateMsg, "角色创建成功：\n" +
                        role.toString() +
                        name + "拥有" + role.getGasNum() + "条先天之气，" +
                        "修炼速度为每次修炼经验基础的" + speed.getSpeed() + "倍。\n" +
                        speed.getInfo() +
                        "\n祝君武道昌隆！");
            });
        }).onError(e -> {
            System.out.println("onError 出错啦: " + e);
        }).onCancel(e -> {
            // 这里是第一个会话，此处通过 onCancel 来处理会话被手动关闭、超时关闭的情况的处理，有些时候会与 orError 同时被触发（例如超时的时候）
            System.out.println("onCancel 关闭啦: " + e);
        }).build(); // build 构建

        // 这里开始等待第一个会话。
        sessionContext.waiting(NAME, accountCode, callback);
    }

    @OnPrivate
    @OnlySession(group = NAME)
    public void name(PrivateMsg m, ListenerContext context, Sender sender) {
        // 得到session上下文。

        final ContinuousSessionScopeContext session = (ContinuousSessionScopeContext) context.getContext(ListenerContext.Scope.CONTINUOUS_SESSION);
        assert session != null;

        final String code = m.getAccountInfo().getAccountCode();
        String text = m.getText().trim();
        if (text.length() <= 6) {
            // 尝试将这个phone推送给对应的会话。
            session.push(NAME, code, text);
        } else {
            sender.sendPrivateMsg(m, "昵称请勿超过6个字符");
        }
    }

    @OnPrivate
    @OnlySession(group = SEX)
    public void onName(PrivateMsg m, ListenerContext context, Sender sender) {
        // 得到session上下文。
        final ContinuousSessionScopeContext session = (ContinuousSessionScopeContext) context.getContext(ListenerContext.Scope.CONTINUOUS_SESSION);
        assert session != null;

        final String code = m.getAccountInfo().getAccountCode();
        String text = m.getText().trim();
        if ("男".equals(text) || "女".equals(text)) {
            // 尝试推送结果
            session.push(SEX, code, text);
        } else {
            sender.sendPrivateMsg(m, "性别选择错误请重新选择(男/女)：");
            session.push(NAME, code, text);
        }
    }

    @OnPrivate
    @Filter(value = "修炼", matchType = MatchType.EQUALS)
    public void cultivation(PrivateMsg privateMsg, ListenerContext context, Sender sender) {

        sender.sendPrivateMsg(privateMsg, "开始修炼...");
        String code = privateMsg.getAccountInfo().getAccountCode();
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", code);
        Role role = roleService.getOne(wrapper);
        if (role == null) {
            sender.sendPrivateMsg(privateMsg, "您未加入大陆，请使用[加入大陆]指令后再进行该操作！");
            return;
        }
        RoleVo roleVo = roleService.cultivation(role);

        if (roleVo.getExpMax().compareTo(roleVo.getExp()) == 0) {
            sender.sendPrivateMsg(privateMsg, "修炼完成,您当前经验值已满，请[突破]后再进行修炼。");
        } else {
            sender.sendPrivateMsg(privateMsg, "修炼完成\n" + roleVo.toString());
        }
    }



    @OnPrivate
    @Filter(value = "突破", matchType = MatchType.EQUALS)
    public void breach(PrivateMsg privateMsg, ListenerContext context, Sender sender) {
        String code = privateMsg.getAccountInfo().getAccountCode();
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("user_id", code);
        Role role = roleService.getOne(roleQueryWrapper);
        if (role == null) {
            sender.sendPrivateMsg(privateMsg, "您未加入大陆，请使用[加入大陆]指令后再进行该操作！");
            return;
        }

        Map<String, Lv> lvMap = RoleServiceImpl.getLvMap();
        Lv lv = lvMap.get(role.getLv() + role.getLvType());
        Speed speed = RoleServiceImpl.getSpeedMap().get(role.getGasNum().longValue());

        if (role.getExp().compareTo(lv.getExpMax()) >= 0) {
            //经验已满，进入升级状态
            // 得到session上下文，并断言它的确不是null
            final ContinuousSessionScopeContext sessionContext = (ContinuousSessionScopeContext) context.getContext(ListenerContext.Scope.CONTINUOUS_SESSION);
            assert sessionContext != null;
            final String accountCode = privateMsg.getAccountInfo().getAccountCode();

            //当从0级提升到1级时需要选择修炼类型
            if (role.getLv() == 0) {
                //0级升到1级需要选择修炼类型
                sender.sendPrivateMsg(privateMsg, "天荒大陆自古以来便是天下修士的得道飞升之地，世人为变强开辟出两条道路：武道一途以先天之气锤炼肉身，从而达到肉身成圣，举手投足间便可抗衡天地，山河破碎；练气一途则是化先天之气为体内丹田，容纳天地本源，借大天地之力化自身小天地之威能，自成一片小天地，颠倒日月，翻手覆山河。\n" +
                        "但这两条道路天生相斥，若非为天地宠儿成为那万中无一的双修奇才，否则只能择一而行，还望三思而后行！\n" +
                        "请选择您的修炼方式[武道]/[练气]：");
                // 创建回调函数 SessionCallback 实例。
                // 通过 SessionCallback.builder 进行创建
                final SessionCallback<String> callback = SessionCallback.<String>builder().onResume(choice -> {
                    sender.sendPrivateMsg(privateMsg, "您选择的修炼途径为：" + choice);
                    //是否为万里挑一的双修奇才
//                    double v = Math.random() * 10000;
//                    if (v<=1){
//                        role.setLvType("双修");
//                        sender.sendPrivateMsg(privateMsg, "叮！您乃万里挑一的武道练气双修的绝世天才！(然而并不会有什么鸟用-暂时)");
//                    } else {
//                        role.setLvType(choice);
//                    }
                    role.setLvType(choice);
                    role.setExp(new BigDecimal(0));
                    role.setLv(role.getLv() + 1);
                    role.setHp(role.getHp() + lv.getHp());
                    role.setAttack(role.getAttack() + lv.getAttack());
                    role.setDefe(role.getDefe() + lv.getDefe());
                    roleService.updateById(role);
                    RoleVo roleVo = new RoleVo();
                    BeanUtils.copyProperties(role, roleVo);
                    roleVo.setExpMax(lvMap.get(role.getLv() + role.getLvType()).getExpMax());
                    roleVo.setLvName(lvMap.get(role.getLv() + role.getLvType()).getName());
                    sender.sendPrivateMsg(privateMsg, "天道酬勤，恭喜您突破成功！\n" +
                            "当前等级每修炼一次获取的经验为：\n" +
                            lv.getExp() + "*" + speed.getSpeed() + "=" + (lvMap.get(role.getLv() + role.getLvType()).getExp().multiply(speed.getSpeed())) + "\n" +
                            roleVo.toString());

                }).onError(e -> System.out.println("onError 出错啦: " + e)).onCancel(e -> {
                    // 这里是第一个会话，此处通过 onCancel 来处理会话被手动关闭、超时关闭的情况的处理，有些时候会与 orError 同时被触发（例如超时的时候）
                    System.out.println("onCancel 关闭啦: " + e);
                }).build(); // build 构建

                // 这里开始等待第一个会话。
                sessionContext.waiting(CHOICE, accountCode, callback);
            } else {
                role.setExp(new BigDecimal(0));
                role.setLv(role.getLv() + 1);
                role.setHp(role.getHp() + lv.getHp());
                role.setAttack(role.getAttack() + lv.getAttack());
                role.setDefe(role.getDefe() + lv.getDefe());

                Lv lv1 = lvMap.get(role.getLv() + role.getLvType());
                if (lv1 == null) {
                    sender.sendPrivateMsg(privateMsg, "您已经达到当前修炼等级巅峰，请等待世界开放后继续修炼。");
                    return;
                }
                roleService.updateById(role);
                RoleVo roleVo = new RoleVo();
                BeanUtils.copyProperties(role, roleVo);
                roleVo.setExpMax(lv1.getExpMax());
                roleVo.setLvName(lv1.getName());
                sender.sendPrivateMsg(privateMsg, "天道酬勤，恭喜您突破成功！\n" +
                        "当前等级每修炼一次获取的经验为：\n" +
                        lv.getExp() + "*" + speed.getSpeed() + "=" + (lv1.getExp().multiply(speed.getSpeed())) + "\n" +
                        roleVo.toString());
            }
        } else {
            sender.sendPrivateMsg(privateMsg, "变强需脚踏实地，一步一个脚印，请您将经验值修满后再进行突破，祝君武道昌隆！");
        }
    }

    @OnPrivate
    @OnlySession(group = CHOICE)
    public void choice(PrivateMsg m, ListenerContext context, Sender sender) {
        // 得到session上下文。

        final ContinuousSessionScopeContext session = (ContinuousSessionScopeContext) context.getContext(ListenerContext.Scope.CONTINUOUS_SESSION);
        assert session != null;

        final String code = m.getAccountInfo().getAccountCode();
        String text = m.getText().trim();
        if ("武道".equals(text) || "练气".equals(text)) {
            // 尝试将这个phone推送给对应的会话。
            session.push(CHOICE, code, text);
        } else {
            sender.sendPrivateMsg(m, "请选择正确的修炼途径");
        }
    }


    @OnPrivate
    @Filter(value = "内视", matchType = MatchType.EQUALS)
    public void look(PrivateMsg privateMsg, Sender sender){
        String code = privateMsg.getAccountInfo().getAccountCode();
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", code);
        Role role = roleService.getOne(queryWrapper);
        if (role == null) {
            sender.sendPrivateMsg(privateMsg, "您未加入大陆，请使用[加入大陆]指令后再进行该操作！");
            return;
        }
        Lv lv = RoleServiceImpl.getLvMap().get(role.getLv() + role.getLvType());
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(role, roleVo);
        roleVo.setExpMax(lv.getExpMax());
        roleVo.setLvName(lv.getName());
        sender.sendPrivateMsg(privateMsg, roleVo.toString());
    }

    @OnPrivate
    @Filter(value = "查阅修炼等级", matchType = MatchType.STARTS_WITH)
    public void lvList(PrivateMsg privateMsg, Sender sender){
        String text = privateMsg.getText().replace("查阅修炼等级", "");

        List<Lv> lvList = lvService.getLvList(text);
        StringBuilder s = new StringBuilder(text + "修炼等级\n");
        for (Lv lv: lvList) {
            s.append(lv.getLv()).append(lv.getName()).append("\n");
        }
        sender.sendPrivateMsg(privateMsg, s.toString());
    }
}
